#include "ScriptHelpers.h"

#include "Render/Render.h"
#include "Render/Texture.h"
#include "Render/Model.h"
#include "Render/Font.h"

using namespace Render;

namespace Binds
{
	static int Bind_Texture(lua_State *L);
	static int Bind_Model(lua_State *L);
	static int Bind_Font(lua_State *L);
	
	static int Bind_Render_beginFrame(lua_State *L)
	{
		Render::beginFrame();
		return 0;
	}
	
	static int Bind_Render_endFrame(lua_State *L)
	{
		Render::endFrame();
		return 0;
	}
	
	static int Bind_Render_drawModel(lua_State *L)
	{
		if (const Model *model = script_cast<Model*>(L, 1))
			Render::drawModel(model);
		return 0;
	}
	
	static int Bind_Render_drawText(lua_State *L)
	{
		if (const Font *font = script_cast<Font*>(L, 1))
		{
			Render::drawText(font,
					lua_isnumber(L, 2) ? lua_tointeger(L, 2) : 0,
					lua_isnumber(L, 3) ? lua_tonumber(L, 3) : 0.0f,
					lua_isnumber(L, 4) ? lua_tonumber(L, 4) : 0.0f,
					lua_isstring(L, 5) ? lua_tostring(L, 5) : ""
				);
		}
		return 0;
	}
	
	static const luaL_Reg Render_Methods[] = {
		{"beginFrame", Bind_Render_beginFrame},
		{"endFrame",   Bind_Render_endFrame},
		{"drawModel",  Bind_Render_drawModel},
		{"drawText",   Bind_Render_drawText},
		{NULL, NULL}
	};
	
	int bindRender(lua_State *L)
	{
		script_bind_methods(L, "Render", Render_Methods);
		
		Bind_Texture(L);
		Bind_Model(L);
		Bind_Font(L);
		
		return 0;
	}
	
	static int Bind_Texture_new(lua_State *L)
	{
		if (lua_isstring(L, 1))
		{
			Texture *texture = script_new(L, Texture)(lua_tostring(L, 1));
			//ASSERT(texture);
			return 1;
		}
		
		return 0;
	}
	
	int Bind_Texture_getWidth(lua_State *L)
	{
		if (const Texture *texture = script_cast<Texture*>(L, 1))
		{
			lua_pushinteger(L, texture->getWidth());
			return 1;
		}
		
		return 0;
	}
	
	int Bind_Texture_getHeight(lua_State *L)
	{
		if (const Texture *texture = script_cast<Texture*>(L, 1))
		{
			lua_pushinteger(L, texture->getHeight());
			return 1;
		}
		
		return 0;
	}
	
	static const luaL_Reg Texture_Methods[] = {
		{"new",       Bind_Texture_new},
		{"__gc",      script_gc<Texture>},
		{"getWidth",  Bind_Texture_getWidth},
		{"getHeight", Bind_Texture_getHeight},
		{NULL, NULL}
	};
	
	static int Bind_Texture(lua_State *L)
	{
		script_bind_methods(L, "Texture", Texture_Methods);
		return 0;
	}
	
	static int Bind_Model_new(lua_State *L)
	{
		if (lua_isstring(L, 1))
		{
			Model *model = script_new(L, Model)(lua_tostring(L, 1));
			//ASSERT(model);
			return 1;
		}
		
		return 0;
	}
	
	static const luaL_Reg Model_Methods[] = {
		{"new",  Bind_Model_new},
		{"__gc", script_gc<Model>},
		{NULL, NULL}
	};
	
	static int Bind_Model(lua_State *L)
	{
		script_bind_methods(L, "Model", Model_Methods);
		return 0;
	}
	
	static int Bind_Font_new(lua_State *L)
	{
		if (lua_isstring(L, 1))
		{
			Font *font = script_new(L, Font)(lua_tostring(L, 1));
			//ASSERT(font);
			return 1;
		}
		
		return 0;
	}
	
	static const luaL_Reg Font_Methods[] = {
		{"new",  Bind_Font_new},
		{"__gc", script_gc<Font>},
		{NULL, NULL}
	};
	
	static int Bind_Font(lua_State *L)
	{
		script_bind_methods(L, "Font", Font_Methods);
		return 0;
	}
}
